home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / fadecode / fade.asm < prev    next >
Assembly Source File  |  1994-08-19  |  13KB  |  461 lines

  1. %TITLE "moduleShell"
  2. ;---------------------------------------------------------------------
  3. ; CAUTION!
  4. ;      This module is written in Ideal model, meaning you need
  5. ;      Borland Turbo Assembler to compile it.
  6. ;------------------------------------------------------------------------
  7.  
  8.        IDEAL
  9.        P286
  10.        include "model.inc"
  11.  
  12.       DATASEG
  13.  
  14.  
  15. PAL_SIZE EQU 768
  16.  
  17.  
  18.        CODESEG
  19.  
  20.  
  21.        PUBLIC   _setpal,_fade_out_once,_bright_out_once
  22.        PUBLIC   _sub_palette,_fade_between_once,_fade_in_once
  23.        PUBLIC   _fill_pal,_copyPal,_rotate_pal
  24.  
  25.  
  26.  
  27. PROC _setpal
  28. ;-----------------------------------------------------------------
  29. ; void setpal(void far *pal)
  30. ; This function simply updates hardware palette using the data
  31. ; stored in char pal[PAL_SIZE]
  32. ;  (PAL_SIZE=768)
  33. ;-----------------------------------------------------------------
  34. ARG pal:dword
  35.  
  36.      push      bp
  37.      mov       bp,sp
  38.      push      ds
  39.      push      di
  40.      push      si
  41.      lds      si,[pal]
  42.      call      SETPAL
  43.      pop       si
  44.      pop       di
  45.      pop       ds
  46.      pop       bp
  47.      ret
  48. ENDP _setpal
  49.  
  50.  
  51. PROC _fade_out_once
  52. ;-----------------------------------------------------------------------
  53. ; void  fade_out_once(void far *pal)
  54. ;
  55. ; *pal points to an array of PAL_SIZE (768) bytes (chars)
  56. ; This routine changes the content of palette array. So if you need to
  57. ; preserve the content of the palette array, you would have to copy
  58. ; the information to another array before calling this routine.
  59. ;
  60. ; Call this routine 32 times to fade out the screen completely.
  61. ;------------------------------------------------------------------------
  62. ARG pal:dword
  63.       push      bp
  64.       mov       bp,sp
  65.       push      ds
  66.       push      di
  67.       push      si
  68.  
  69.        lds      si,[pal]            ; ds:si points to the palette array
  70.  
  71.       mov       cx,PAL_SIZE
  72.  
  73. @@fl1:cmp       [byte ptr si],0     ; if [ds:si]=0 goto @@fade2
  74.       je        @@fade2             ;
  75.       cmp       [byte ptr si],1     ; if [ds:si]=1 goto @@fade1
  76.       je        @@fade1
  77.       dec       [byte ptr si]       ; [ds:si]=[ds:si]-1
  78. @@fade1:dec       [byte ptr si]
  79. @@fade2:inc       si                ; si=si+1
  80.       loop      @@fl1
  81.  
  82.       sub       si,PAL_SIZE         ; restore si
  83.  
  84.       call       SETPAL
  85.       pop       si
  86.       pop       di
  87.       pop       ds
  88.       pop       bp
  89.       ret
  90.  
  91. ENDP _fade_out_once
  92.  
  93.  
  94. PROC _bright_out_once
  95. ;-------------------------------------------------------------
  96. ; bright_out_once(char far *pal)
  97. ;
  98. ; It works very much like fade_once() function. But it brightens
  99. ; the screen, instead of darkening the screen.
  100. ; Call this function 32 times to whiten the screen completely.
  101. ;-------------------------------------------------------------
  102. ARG pal:dword
  103.       push      bp
  104.       mov       bp,sp
  105.       push      ds                ; let's preserve some registers
  106.       push      di
  107.       push      si
  108.  
  109.       lds      si,[pal]            ;ds:si points to the palette array
  110.  
  111.       mov       cx,PAL_SIZE
  112.  
  113. @@b1:cmp       [byte ptr si],62   ; if pal[si]<62
  114.       jge        @@b2
  115.       inc       [byte ptr si]      ; pal[si]=pal[si]+2
  116.       inc       [byte ptr si]
  117. @@b2:
  118.       cmp       [byte ptr si],63   ;else if pal[si]<63
  119.       je        @@b3
  120.       inc       [byte ptr si]      ; pal[si]=pal[si]+1
  121. @@b3:
  122.       inc       si                 ; si=si+1;
  123.       loop      @@b1
  124.  
  125. ;-----update palette
  126.       sub       si,PAL_SIZE              ; restore the value of si
  127.                     ; now ds:si again points to the
  128.                     ; beginning of the palette array
  129.  
  130.       call      SETPAL
  131.  
  132.       pop       si
  133.       pop       di
  134.       pop       ds
  135.       pop       bp
  136.       ret
  137.  
  138. ENDP _bright_out_once
  139.  
  140.  
  141.  
  142. PROC _sub_palette
  143. ;----------------------------------------------------------------------
  144. ; sub_palette(void *pal,void far *pal_dest)
  145. ; This routine prepares the palettes for fade_between_once()
  146. ; function.
  147. ; WARNING: pal points to char array of 768*2 bytes, not 768 bytes
  148. ;----------------------------------------------------------------------
  149. ARG pal:dword,pal_dest:dword
  150.       push   bp
  151.       mov    bp,sp
  152.       push   ds
  153.       push   di
  154.       push   si
  155.  
  156.       lds    si,[pal]          ;ds:si points to pal[]
  157.       les    di,[pal_dest]     ;es:di points to pal_dest[]
  158.  
  159.       mov    cx,PAL_SIZE       ; the following loop is basically
  160. @@l:  lodsb                    ; for(n=0;n<768;++n)
  161.       sub    [es:di],al        ;  pal_dest[n]=pal_dest[n]-pal[n];
  162.       inc    di                ;
  163.       loop   @@l
  164.  
  165.       mov    cx,PAL_SIZE/2     ; the following loop is equivalent to
  166.       xor    ax,ax
  167. @@l2: mov    [ds:si],ax        ; for(n=0;n<768;++n)
  168.       inc    si                ;  pal[n+PAL_SIZE]=0;
  169.       inc    si
  170.       loop   @@l2
  171.  
  172.       pop     si
  173.       pop     di
  174.       pop     ds
  175.       pop     bp
  176.       ret
  177. ENDP _sub_palette
  178.  
  179.  
  180.  
  181.  
  182. PROC _fade_between_once
  183. ;-------------------------------------------------------------------
  184. ; fade_between_once(void far *pal,void far *pal_dest)
  185. ; call sub_palette first
  186. ; Which will destroy original values of pal_dest,
  187. ;    but it's a necessary step.
  188. ; After calling it 63 times,the content of pal[768] will become
  189. ; identical to the original values of pal_dest anyway :)
  190. ;-------------------------------------------------------------------
  191. ARG  pal:dword,pal_dest:dword
  192.      push   bp
  193.      mov    bp,sp
  194.      push   ds
  195.      push   di
  196.      push   si
  197.      lds    si,[pal]
  198.      les    di,[pal_dest]
  199.  
  200.      cld
  201.      push   si
  202.  
  203.       mov     cx,PAL_SIZE
  204. fl2:                         ; increase the value of pallettes
  205.       mov     bl,[es:di]     ; es:di = dest_pal
  206.       cmp     bl,0
  207.       jl      fl4            ; if bl>0 then goto fl4
  208.  
  209.       add     [PAL_SIZE+si],bl
  210.       jmp     fl3
  211.  
  212. fl4:  neg     bl
  213.       add     [PAL_SIZE+si],bl
  214. fl5:  cmp     [byte ptr PAL_SIZE+si],63
  215.       jb      fl7
  216.       dec     [byte ptr si]
  217.       sub     [byte ptr PAL_SIZE+si],63
  218.       jmp     fl7
  219.  
  220. fl3:  cmp     [byte ptr PAL_SIZE+si],63
  221.       jb      fl7      ;
  222.       inc     [byte ptr si] ; increase by one
  223.       sub     [byte ptr PAL_SIZE+si],63
  224. fl7:  inc     di
  225.       inc     si
  226.       loop    fl2
  227.  
  228.  
  229.      pop     si
  230.      call    Setpal
  231.  
  232.      pop     si
  233.      pop     di
  234.      pop     ds
  235.      pop     bp
  236.      ret
  237. ENDP _fade_between_once
  238.  
  239.  
  240. PROC _fade_in_once
  241. ;------------------------------------------------------------------------
  242. ; fadein_once(void far *pal,void far *pal_dest)
  243. ; warning: pal should point to an array of 768*2 (NOT 768) BLANK bytes
  244. ; call this function 32 times to fade in the screen completely.
  245. ;-------------------------------------------------------------------------
  246.      ARG pal:dword,pal_dest:dword
  247.       push    bp
  248.       mov     bp,sp
  249.       push    ds                  ; let's save some registers as usual
  250.       push    di
  251.       push    si
  252.  
  253.       lds     si,[pal]            ;ds:si points to pal
  254.       les     di,[pal_dest]       ;es:di points to pal_dest
  255.  
  256.       cld
  257.       push    si             ;ds:si=pal
  258.       mov     cx,PAL_SIZE
  259. bl2:                         ; increase the value of pallettes
  260.       mov     bl,[es:di]     ; es:di = dest_pal
  261.       add     [PAL_SIZE+si],bl
  262. bl3:  cmp     [byte ptr PAL_SIZE+si],32
  263.       jb      @@bl7      ;
  264.       inc     [byte ptr si] ; increase by one
  265.       sub     [byte ptr PAL_SIZE+si],32
  266.       jmp     bl3
  267. @@bl7:inc     di
  268.       inc     si
  269.       loop    bl2
  270.  
  271.       pop     si             ; restore si
  272.  
  273.       call    SETPAL
  274.       pop     si
  275.       pop     di
  276.       pop     ds
  277.       pop     bp
  278.       ret
  279. ;      jmp     SETPAL         ; I probably don't need this but just to
  280.                  ; make sure...
  281.  
  282. ENDP _fade_in_once
  283.  
  284.  
  285. PROC _rotate_pal
  286. ;--------------------------------------------------------------------
  287. ; rotate_pal(void far *pal,char index, char numCOl,unsigned char displacement)
  288. ;
  289. ; note this carefully.
  290. ; this routine DOES preserve the content of pal[]
  291. ; Let me give you an example how this routine works.
  292. ;
  293. ; rotate_pal(&pal,63,32,0);
  294. ;  this routine will update palette number from 63-95.
  295. ;  but no rotation will take place
  296. ; rotate_pal(&pal,63,32,1);
  297. ;  this routine will also update palette number from 63-95.
  298. ;  but this time, the color #64 will replace the content of color #63
  299. ;  and color #65 will replace #66 etc.
  300. ;
  301. ; keep it in mind that this routine does NOT change the content of pal[]
  302. ;
  303. ;---------------------------------------------------------------------
  304. ARG pal:dword,index:byte,numCol:byte,displacement:byte
  305.  
  306.       push    bp
  307.       mov     bp,sp
  308.       push    ds
  309.       push    di
  310.       push    si
  311.  
  312.       lds     si,[pal]
  313.  
  314.       mov     ax,3
  315.       mul     [index]         ; ax=index*3
  316.       add     si,ax              ; si=si+ax
  317.  
  318.       push    si                 ; preserve si
  319.  
  320.       mov     ax,3
  321.       mul     [byte ptr displacement]
  322.       add     si,ax
  323.  
  324.       mov     bh,[index]
  325.       mov     bl,1
  326.       xor     ch,ch
  327.       mov     cl,[numCol]         ;cx=(numCol-displacement)*3
  328.       sub     cl,[byte ptr displacement]
  329.       mov     ax,cx
  330.       add     cx,cx
  331.       add     cx,ax
  332.  
  333.  
  334.       call    SETPAL2
  335.  
  336.       pop     si
  337.       mov     bh,[index]
  338.       add     bh,[numCol]
  339.       sub     bh,[displacement]
  340.       mov     bl,1
  341.       mov     ax,3
  342.       mul     [displacement]    ; cx=displacement*3
  343.       mov     cx,ax
  344.       call    SETPAL2
  345.  
  346.  
  347.       pop     si
  348.       pop     di
  349.       pop     ds
  350.       pop     bp
  351.       ret
  352. ENDP _rotate_pal
  353.  
  354.  
  355.  
  356. ;-------------------------------------------------------------------------
  357. ; update the hardware palette
  358. ; input: ds:si points to palette array
  359. ;-------------------------------------------------------------------------
  360.  
  361.  
  362. PROC SETPAL
  363.       mov       bh,0               ; bh=# of the first palette color to
  364.                    ; update.
  365.       mov       bl,2               ;This is the loop index.
  366.                    ;In the following codes, we are updating
  367.                    ;128 color at a time. Therefore, we need
  368.                    ;a loop that runs twice in order to update
  369.                    ;all 256 colors.
  370.  
  371.     mov     cx,128*3         ; di=128(the number of colors to update)*3
  372.  
  373. PROC SETPAL2
  374. s:
  375.     mov dx, 03DAh               ; CRT controller input status 1 register
  376. v1:
  377.     in    al, dx
  378.     test   al,08h
  379.     jnz    v1                     ; wait until vertical retrace starts
  380. v2:
  381.     in     al, dx
  382.     test   al,08h                 ; wait until vertical retrace ends
  383.         jz     v2
  384.  
  385.  ;--------- We have done waiting. Now let's update the palette
  386.     mov     al,bh            ; get first color # to process into al
  387.     mov     dx, 03c8h        ; DAC palette index register
  388.  
  389.     push    cx
  390.     out     dx, al           ; Write the register number to the dac
  391.     inc     dx
  392.     rep     outsb
  393.     pop     cx
  394.  
  395.     add     bh,128           ; color index=color index+128
  396.     dec     bl
  397.     jnz     s
  398.  
  399.       ret
  400. ;----------------------------------------
  401.  
  402. ENDP SETPAL2
  403.  
  404.  
  405.  
  406.  
  407. PROC _fill_pal
  408. ;-------------------------------------------------------------
  409. ; fill_pal(void far *pal, char red, char green, char blue);
  410. ; fills the palette array with the color data given
  411. ; does not update hardware palette
  412. ;-------------------------------------------------------------
  413. ARG pal:dword, red:byte, green:byte,blue:byte
  414.       push   bp
  415.       mov    bp,sp
  416.       push   di
  417.       les    di,[pal]
  418.       cld
  419.       mov    cx,PAL_SIZE/3
  420.       mov    al,[red]
  421.       mov    ah,[green]
  422.       mov    bl,[blue]
  423. @@fpl:mov    [es:di],al
  424.       mov    [es:di+1],ah
  425.       mov    [es:di+2],bl
  426.       add    di,3
  427.       loop   @@fpl
  428.       pop    di
  429.       pop    bp
  430.       ret
  431. ENDP _fill_pal
  432.  
  433.  
  434. PROC _copyPal
  435. ;----------------------------------------------------------------
  436. ; copyPal(void far *source,void far *dest:dword)
  437. ;
  438. ; both *source and *dest points to arrays of 768 bytes (chars)
  439. ; I know there are C functions out there to copy strings. But
  440. ; I wrote this anyway. What the heck, it only took me a minute.
  441. ;----------------------------------------------------------------
  442. ARG source:dword,dest:dword
  443.       push   bp
  444.       mov    bp,sp
  445.       push   ds
  446.       push   di
  447.       push   si
  448.  
  449.       cld
  450.       les    di,[dest]
  451.       lds    si,[source]
  452.       mov    cx,PAL_SIZE
  453.       rep    movsb
  454.       pop    si
  455.       pop    di
  456.       pop    ds
  457.       pop    bp
  458.       ret
  459. ENDP _copyPal
  460.  
  461.       END                     ; End of module